package com.chenfan.process.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.chenfan.ccp.entity.BaseEntity;
import com.chenfan.process.entity.dto.InstanceSnapshotDTO;
import com.chenfan.process.entity.po.*;
import com.chenfan.process.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author liuming
 * @date 2021/10/19
 */
@Service
public class ApprovalSnapshotDomainService {

    @Autowired
    protected ApprovalSnapshotPoService approvalSnapshotPoService;
    @Autowired
    private ProcessRelatedService processRelatedService;

    @Autowired
    private ApprovalTemplateSnapshotService approvalTemplateSnapshotService;
    @Autowired
    private ProcessFormNodeRelationService processFormNodeRelationService;
    @Autowired
    private ProcessRelatedAttributeService processRelatedAttributeService;
    @Autowired
    private ProcessService processService;

    public void save(ApprovalPo approvalPo, ApprovalTemplatePo template, Long version) {
        List<ProcessRelatedPo> processRelations =
            processRelatedService.listProcessRelatedAfterProcessId(approvalPo.getApprovalTemplateId(), version, null);
        ApprovalSnapshotPo approvalSnapshotPo = ApprovalSnapshotPo.ofDefault(approvalPo.getApprovalId());

        // 保存快照数据
        InstanceSnapshotDTO instanceSnapshot = new InstanceSnapshotDTO();
        instanceSnapshot.setProcessRelatedPoList(processRelations);
        // 找到节点的属性关系
        Set<Long> node = new HashSet<>();
        processRelations.forEach(e -> {
            node.add(e.getProcessBeforeId());
            node.add(e.getProcessAfterId());
        });
        List<Long> relationIdList = processRelations.stream().map(BaseEntity::getId).collect(Collectors.toList());

        List<ProcessPo> processPos = processService.listByIds(node);
        instanceSnapshot.setProcessList(processPos);


        approvalSnapshotPo.setRelation(JSONObject.toJSONString(instanceSnapshot));
        // 同时保存相关的快照信息
        if (Objects.nonNull(template) && Objects.nonNull(template.getApprovalSnapshotId())) {
            ApprovalTemplateSnapshotPo approvalSnapshot =
                approvalTemplateSnapshotService.getById(template.getApprovalSnapshotId());
            approvalSnapshotPo.setApprovalTemplateSnapshot(approvalSnapshot.getContent());
        }
        approvalSnapshotPoService.save(approvalSnapshotPo);
    }

    public List<ProcessRelatedPo> getRelation(Long approvalId, Long processId, ProcessDetailPo processDetailById) {
        ApprovalSnapshotPo approvalSnapshot = approvalSnapshotPoService.getByApprovalId(approvalId);
        InstanceSnapshotDTO instanceSnapshot =
                JSONObject.parseObject(approvalSnapshot.getRelation(), InstanceSnapshotDTO.class);
        List<ProcessRelatedPo> processRelatedPos = instanceSnapshot.getProcessRelatedPoList();
        if (Objects.nonNull(processDetailById.getGroupId())) {
            List<ProcessRelatedPo> collect = processRelatedPos.stream().filter(e -> Objects.equals(e.getGroupId(), processDetailById.getGroupId()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                processId = collect.get(0).getProcessAfterId();
            }
        }
        Long finalProcessId = processId;
        return processRelatedPos.stream().filter(e -> Objects.equals(e.getProcessBeforeId(), finalProcessId))
            .collect(Collectors.toList());
    }


    public List<ProcessRelatedPo> getWithGroup(Long approvalId, Long processId, Long groupId) {
        ApprovalSnapshotPo approvalSnapshot = approvalSnapshotPoService.getByApprovalId(approvalId);
        InstanceSnapshotDTO instanceSnapshot =
                JSONObject.parseObject(approvalSnapshot.getRelation(), InstanceSnapshotDTO.class);
        List<ProcessRelatedPo> processRelatedPos = instanceSnapshot.getProcessRelatedPoList();
        if (Objects.nonNull(groupId)) {
            return processRelatedPos.stream().filter(e -> Objects.equals(e.getGroupId(), groupId))
                    .collect(Collectors.toList());
        }
        return processRelatedPos.stream().filter(e -> Objects.equals(e.getProcessBeforeId(), processId))
                .collect(Collectors.toList());
    }
}
